<html>
 <head>
  <title>BachPool</title>
 </head>
 <body onloaded="animate()">
  <script src="https://closure-library.googlecode.com/svn/trunk/closure/goog/base.js"></script>
  <canvas id="pane" width="600" height="400" onclick="click(this)"/>
  <script>
 goog.require('goog.async.Delay');
  </script>
  <script>

 //const
 var pane=document.getElementById('pane');
 //const
 var ctx=pane.getContext('2d');

 var balls = [
  // first ball is used by queue
  {color:'#fff', x:500, y:200},
  {color:'rgb(248,148,183)', x:200, y:120},
  {color:'#888', x:200, y:160},
  {color:'#f0f', x:200, y:200},
  {color:'#0ff', x:200, y:240},
  {color:'#0ff', x:200, y:280},
  {color:'#ff0', x:240, y:140},
  {color:'#ff0', x:240, y:180},
  {color:'#f0f', x:240, y:220},
  {color:'#ff0', x:240, y:260},
  {color:'#ff0', x:280, y:160},
  {color:'#ff0', x:280, y:200},
  {color:'#ff0', x:280, y:240},
  {color:'#777', x:320, y:180},
  {color:'#777', x:320, y:220},
  {color:'#777', x:360, y:200},
 ];
 for(var i=0; i<balls.length;i++) {
  var b=balls[i];
  b.x-=100;
  b.y-=10;
  b.vx=0;
  b.vy=0;
 }

 function arrowedArc(x,y,r,s,e,c) {
  ctx.lineWidth=1.5;
  ctx.beginPath();
  ctx.arc(x, y, r, s/4*Math.PI, e/4*Math.PI);
  ctx.stroke();
  for(var i=6;i>0;i--) {
   ctx.lineWidth=i;
   ctx.beginPath();
   if(c) {
    ctx.arc(x, y, r, (e/4-i/100)*Math.PI, (e/4-(i-1)/100)*Math.PI);
   } else {
    ctx.arc(x, y, r, (s/4+i/100)*Math.PI, (s/4+(i+1)/100)*Math.PI);
   }
   ctx.stroke();
  }
 }

 var r=12;
 var border=32;

 //toggled by mousedown/mouseup:
 var fireQueue=false;
 var startX;
 var startY;
 var endX;
 var endY;

 function draw() {
   ctx.fillStyle='#C3632D';
   ctx.fillRect(0,0,600,400);
   ctx.fillStyle='#080';
   ctx.fillRect(border,border,600-2*border,400-2*border);

   ctx.fillStyle='#000';

   ctx.beginPath();
   ctx.arc(border,    border,    2*r,Math.PI/2, 2*Math.PI);
   ctx.closePath();
   ctx.fill();
   
   ctx.beginPath();
   ctx.arc(300,       border,    2*r,Math.PI, 2*Math.PI);
   ctx.closePath();
   ctx.fill();

   ctx.beginPath();
   ctx.arc(600-border,border,    2*r,Math.PI, 1/2*Math.PI);
   ctx.closePath();
   ctx.fill();

   ctx.beginPath();
   ctx.arc(border,    400-border,2*r,0, 3/2*Math.PI);
   ctx.closePath();
   ctx.fill();

   ctx.beginPath();
   ctx.arc(600-border,400-border,2*r,3/2*Math.PI, Math.PI);
   ctx.closePath();
   ctx.fill();

   ctx.beginPath();
   ctx.arc(border,600-border,
    2*r,0, 3/2*Math.PI);
   ctx.closePath();
   ctx.fill();

   for(var i=0; i<balls.length;i++) {
    var b=balls[i];
    ctx.fillStyle=b.color;
    ctx.beginPath();
    ctx.arc(b.x,b.y,
     r,0,2*Math.PI);
    ctx.closePath();
    ctx.fill();
   }
   var dX=endX-startX;
   var dY=endY-startY;
   for(var i=0; i<4; i++) {
    ctx.lineWidth=i+2;
    ctx.beginPath();
    ctx.moveTo(startX+dX*i/4,startY+dY*i/4);
    ctx.lineTo(startX+dX*(i+1)/4,startY+dY*(i+1)/4);
    ctx.closePath();
    ctx.stroke();
   }

/*  ctx.font="14px Arial";
  ctx.fillStyle='#f00';
  ctx.strokeStyle='#f00';
  ctx.fillText('x',20,110);
  arrowedArc(22,109,20,5,7,false);
  arrowedArc(22,64,20,1,3,true);
  ctx.beginPath();
  ctx.moveTo(25,110);
  ctx.lineTo(65,70);
  ctx.lineWidth=2;
  ctx.stroke();

  ctx.fillStyle='#0f0';
  ctx.strokeStyle='#0f0';
  ctx.fillText('y',90,65);
  arrowedArc(91,56,40,7,1,false);
  arrowedArc(133,64,40,3,5,true);

  ctx.fillStyle='#00f';
  ctx.strokeStyle='#00f';
  ctx.fillText('z',40,25);
  arrowedArc(71,56,40,5,7,true);
  arrowedArc(65,24,40,1,3,false);
*/
 }

 function animate() {
  //console.log("MOVE!");
  for(var i=0; i<balls.length;i++) {
   var b=balls[i];
   if (
    (b.x<2*r+border && b.y<2*r+border) ||
    //(b.x>300-2*r-border && b.y<2*r+border) ||
    (b.x>600-2*r-border && b.y<2*r+border) ||
    (b.x<2*r+border && b.y>400-2*r-border) ||
    (b.x>600-2*r-border && b.y>400-2*r-border)) {
    if(0==i) {
     b.x=400;
     b.y=190;
     b.vx=0;
     b.vy=0;
    } else {
     b.x=-100;
     b.y=-100;
    }
   }
   b.x+=b.vx/5;
   if (b.x<r+border||b.x>600-r-border) {
    b.vx=-b.vx;
   }
   b.y+=b.vy/5;
   if (b.y<r+border ||b.y>400-r-border) {
    b.vy=-b.vy;
   }
   b.vx=0.98*b.vx;//Math.max(0,b.vx-1);
   b.vy=0.98*b.vy;//Math.max(0,b.vy-1);
   for(var j=0; j<balls.length;j++) {
    if(i!=j) {
     var bn=balls[j];
     if( 4*r*r > Math.pow(b.x-bn.x,2)+ Math.pow(b.y-bn.y,2)) {
      bn.vx=b.vx;
      bn.vy=b.vy;
      b.vx=b.vx/2;
      b.vy=b.vy/2;
     }
    }
   }
  }
  draw();
  var delay = new goog.async.Delay(animate, 50);
  delay.start();
 }

 function fire(event) {
  var x = event.pageX - pane.offsetLeft;
  var y = event.pageY - pane.offsetTop;
  if (x>0 && y>0) {
   //console.log("FIRE!");
   balls[0].vx=queueStartX-x;
   balls[0].vy=queueStartY-y;
   draw();
   fireQueue=false;
  }
 }

 function tfire(event) {
  //event.preventDefault();
  var x = event.targetTouches[0].pageX - pane.offsetLeft;
  var y = event.targetTouches[0].pageY - pane.offsetTop;
  if (x>0 && y>0) {
   //console.log("FIRE!");
   balls[0].vx=queueStartX-x;
   balls[0].vy=queueStartY-y;
   draw();
   fireQueue=false;
  }
 }

 function click(event) {
  var x = event.pageX - pane.offsetLeft;
  var y = event.pageY - pane.offsetTop;
  if (x>0 && y>0) {
   queueStartX=x;
   queueStartY=y;
   endX=x+40;
   endY=y+40;
   fireQueue=true;
   draw();
  }
 }

 function tclick(event) {
  //event.preventDefault();
  var x = event.targetTouches[0].pageX - pane.offsetLeft;
  var y = event.targetTouches[0].pageY - pane.offsetTop;
  if (x>0 && y>0) {
   queueStartX=x;
   queueStartY=y;
   endX=x+40;
   endY=y+40;
   fireQueue=true;
   draw();
  }
 }

 function tmove(event) {
  //event.preventDefault();
  //http://stackoverflow.com/questions/9880279/how-do-i-add-a-simple-onclick-event-handler-to-a-canvas-element
  var x = event.targetTouches[0].pageX - pane.offsetLeft;
  var y = event.targetTouches[0].pageY - pane.offsetTop;
  if (x>0 && y>0) {
   if(fireQueue) {
    endX=x;
    endY=y;
   } else {
    startX=x;
    startY=y;
    endX=x+80;
    endY=y+40;
   }
   draw();
  }
 }

 function move(event) {
  //http://stackoverflow.com/questions/9880279/how-do-i-add-a-simple-onclick-event-handler-to-a-canvas-element
  var x = event.pageX - pane.offsetLeft;
  var y = event.pageY - pane.offsetTop;
  if (x>0 && y>0) {
   if(fireQueue) {
    endX=x;
    endY=y;
   } else {
    startX=x;
    startY=y;
    endX=x+80;
    endY=y+40;
   }
   draw();
  }
 }
 //pane.addEventListener('click',fire,false);
 pane.addEventListener('mousedown',click,false);
 pane.addEventListener('touchstart',tclick,false);
 pane.addEventListener('mousemove',move,false);
 pane.addEventListener('touchmove',tmove,false);
 pane.addEventListener('mouseup',fire,false);
 pane.addEventListener('touchend',tfire,false);
 //pane.addEventListener('dblclick',click,false);
animate();
</script>
 </body>
</html>